(ns scripts.cljmon.excel
  (:use poi.excel
        util.file)
  (:require clojure.string))

(defn- parse-pids [comments]
  (into {}
    (for [comment comments :when (re-find #"pid:\s*(\d+)" comment)]
      [(second (re-find #"pid:\s*(\d+)" comment)) (clojure.string/replace comment #",\s+" "\n")])))

(defn- parse-nics [comments]
  (into {}
    (for [comment comments :when (re-matches #"Network Interface (\w+) -> (.*)" comment)]
      (vec (rest (re-matches #"Network Interface (\w+) -> (.*)" comment))))))

(defn- header-comments [pids nics]
  (into {}
    (apply concat
      (for [[nic comment] nics] [(str nic " Network") comment])
      (for [[pid comment] pids]
        [[(str pid " CPU") comment]
         [(str pid " VM (MB)") comment]
         [(str pid " VM (MB)") comment]]))))

(defn convert-cljmon-log-to-excel
  ([log excel]
    (let [logs (clojure.string/split-lines (slurp log))
          [comments logs] (split-with #(= (first %) \#) logs)
          comments (->> comments (map #(clojure.string/replace % #"^#\s*" "")) (remove clojure.string/blank?))
          pids (parse-pids comments)
          nics (parse-nics comments)
          comments (header-comments pids nics)
          [header & logs] (map #(clojure.string/split % #",\s*") logs)]
      (let [book (workbook)
            sheet (create-sheet book "cljmon")
            format (create-data-format book)
            integer-style (doto (create-cell-style book) (set-data-format (get-format format "0")))
            double-style  (doto (create-cell-style book) (set-data-format (get-format format "0.00")))]
        (let [row (create-row sheet 0)]
          (doseq [[i x] (map-indexed vector header)]
            (let [cell (create-cell row i)]
              (set-cell-value cell x)
              (when-let [comment (comments x)]
                (set-cell-comment book sheet cell comment)))))
        (doseq [[ri fields] (map vector (next (range)) logs)]
          (let [row (create-row sheet ri)]
            (doseq [[i x] (map-indexed vector fields)]
              (let [cell (create-cell row i)]
                (cond
                  (re-matches #"\d+" x) (set-cell-style cell integer-style)
                  (re-matches #"\d+\.\d+" x) (set-cell-style cell double-style))
                (set-cell-value cell (auto-cell-value x))))))
        (dotimes [i (count header)]
          (auto-size-column sheet i))
        (save-workbook book excel))))
  ([log]
    (convert-cljmon-log-to-excel log (file-join (file-dirname log) "cljmon.xls"))))


